package com.zzedu.manager.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.zzedu.common.enums.CommonEnums;
import com.zzedu.device.req.GetByIdSubjectContent;
import com.zzedu.device.rsp.ApiZzSubjectContentVO;
import com.zzedu.domain.*;
import com.zzedu.dto.subject.*;
import com.zzedu.enmuns.InteractionTemplateEnums;
import com.zzedu.enmuns.InteractionTypeEnums;
import com.zzedu.enmuns.SubjectTypeEnums;
import com.zzedu.enmuns.WordsAttrEnum;
import com.zzedu.manager.IZzSubjectContentManager;
import com.zzedu.manager.IZzUploadFileManager;
import com.zzedu.result.Result;
import com.zzedu.result.ResultEnum;
import com.zzedu.service.*;
import com.zzedu.vo.ZzUploadFileVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
public class ZzSubjectContentManagerImpl implements IZzSubjectContentManager {
    @Autowired
    IZzUploadFileManager zzUploadFileManager;

    @Autowired
    IZzSubjectContentService zzSubjectContentService;

    @Autowired
    IZzThesaurusWordsService zzThesaurusWordsService;

    @Autowired
    IZzThesaurusAttrService zzThesaurusAttrService;
    @Autowired
    IZzPictureNodeService zzPictureNodeService;

    @Autowired
    IZzPictureBookService zzPictureBookService;

    /**
     * 单词标签
     */
    @Autowired
    IZzThesaurusWordsTagRelatedService zzThesaurusWordsTagRelatedService;
    @Autowired
    IZzThesaurusTagService zzThesaurusTagService;

    @Override
    public Result<ApiZzSubjectContentVO> getById(GetByIdSubjectContent getByIdSubjectContent) {
        Result<ApiZzSubjectContentVO> result = new Result<>();
        result.setResultCode(ResultEnum.SUCCESS.getCode());
        result.setResultMessage(ResultEnum.SUCCESS.getDesc());
        result.setData(convertVO(zzSubjectContentService.getById(getByIdSubjectContent.getId())));
        return result;
    }

    /**
     * 转换对象
     *
     * @param zzSubjectContent
     * @return Mono<ApiZzSubjectContentVO>
     */
    private ApiZzSubjectContentVO convertVO(ZzSubjectContent zzSubjectContent) {
        Assert.notNull(zzSubjectContent, "查询内容不存在");
        ApiZzSubjectContentVO apiZzSubjectContentVO = new ApiZzSubjectContentVO();
        apiZzSubjectContentVO.setId(zzSubjectContent.getId());
        apiZzSubjectContentVO.setTitle(zzSubjectContent.getTitle());
        apiZzSubjectContentVO.setSubjectType(SubjectTypeEnums.getCode(zzSubjectContent.getSubjectType()));
        apiZzSubjectContentVO.setInteraction(InteractionTypeEnums.getCode(zzSubjectContent.getInteraction()));
        apiZzSubjectContentVO.setTemplate(InteractionTemplateEnums.getCode(zzSubjectContent.getTemplate()));
        apiZzSubjectContentVO.setContent(convert(apiZzSubjectContentVO, zzSubjectContent, zzSubjectContent.getContent()));
        return apiZzSubjectContentVO;
    }

    /**
     * 响应式转换 content 字段为 ContentVideoVO，并异步获取文件 URL
     *
     * @param apiZzSubjectContentVO 当前题目内容 VO
     * @param content               JSON 字符串形式的内容
     * @return Mono<ContentVideoVO>
     */
    private BaseContentDTO convert(ApiZzSubjectContentVO apiZzSubjectContentVO, ZzSubjectContent zzSubjectContent, String content) {
        if (SubjectTypeEnums.video == apiZzSubjectContentVO.getSubjectType()) {
            ContentVideoDTO contentVideoDTO = JSON.parseObject(content, ContentVideoDTO.class);
            if (null != contentVideoDTO.getVideoFlag() && 0 == contentVideoDTO.getVideoFlag()) {
                ZzPictureNode zzPictureNode = zzPictureNodeService.getById(zzSubjectContent.getNodeId());
                if (null != zzPictureNode && null != zzPictureNode.getNodeType()) {
                    //课件
                    if (1 == zzPictureNode.getNodeType()) {
                        ZzPictureBook zzPictureBook = this.zzPictureBookService.getById(zzPictureNode.getPictureBookId());
                        if (null != zzPictureBook) {
                            List<Long> fileIdList = JSON.parseArray(zzPictureBook.getVideo(), Long.class);
                            if (CollectionUtils.isNotEmpty(fileIdList)) {
                                contentVideoDTO.setFileId(fileIdList.get(0));
                            }
                        }
                    } else if (2 == zzPictureNode.getNodeType()) {
                        //作业
                        ZzPictureNode dayZzPictureNode = zzPictureNodeService.getById(zzPictureNode.getpNodeId());
                        ZzPictureBook zzPictureBook = this.zzPictureBookService.getById(zzPictureNode.getPictureBookId());
                        if (null != zzPictureBook) {
                            List<Long> fileIdList = JSON.parseArray(zzPictureBook.getVideo(), Long.class);
                            if (CollectionUtils.isNotEmpty(fileIdList)) {
                                contentVideoDTO.setFileId(fileIdList.get(0));
                            }
                        }
                    }
                }
            }
            if (contentVideoDTO.getFileId() != null) {
                // 异步根据 fileId 获取文件信息
                ZzUploadFileVO zzUploadFileVO = zzUploadFileManager.getById(contentVideoDTO.getFileId());
                contentVideoDTO.setFileVideoURL(null != zzUploadFileVO ? zzUploadFileVO.getUrl() : null);
            }
            if (null != contentVideoDTO.getImageFileId()) {
                ZzUploadFileVO zzUploadFileVO = zzUploadFileManager.getById(contentVideoDTO.getImageFileId());
                contentVideoDTO.setImageFileURL(null != zzUploadFileVO ? zzUploadFileVO.getUrl() : null);
            }
            return contentVideoDTO;
        } else if (SubjectTypeEnums.image == apiZzSubjectContentVO.getSubjectType()) {
            ContentImageDTO contentImageDTO = JSON.parseObject(content, ContentImageDTO.class);
            List<Long> fileIdList = Stream.concat
                    (Optional.ofNullable(contentImageDTO.getMusicFileId()).orElse(Lists.newArrayList()).stream(),
                            Stream.of(contentImageDTO.getImageFileId(),
                                    contentImageDTO.getAudioFileId()
                            ).filter(Objects::nonNull)
                    ).collect(Collectors.toList());
            Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
            contentImageDTO.setAudioFileURL(getUrlFromMap(fileMap, contentImageDTO.getAudioFileId()));
            contentImageDTO.setMusicFileURL(Lists.newArrayList());
            if (CollectionUtils.isNotEmpty(contentImageDTO.getMusicFileId())) {
                for (Long id : contentImageDTO.getMusicFileId()) {
                    contentImageDTO.getMusicFileURL().add(getUrlFromMap(fileMap, id));
                }

            }
            contentImageDTO.setImageFileURL(getUrlFromMap(fileMap, contentImageDTO.getImageFileId()));
            return contentImageDTO;
        } else if (SubjectTypeEnums.interaction == apiZzSubjectContentVO.getSubjectType()) {
            if (InteractionTypeEnums.line == apiZzSubjectContentVO.getInteraction()) {
                //连线
                return getContentInteractionLineDTOMono(content, apiZzSubjectContentVO.getTemplate());
            } else if (InteractionTypeEnums.fill_in_the_blanks == apiZzSubjectContentVO.getInteraction()) {
                //选词填空
                return getContentInteractionToFillInTheBlanksDTOMono(content);
            } else if (InteractionTypeEnums.mask_layer == apiZzSubjectContentVO.getInteraction()) {
                //蒙层
                return getContentInteractionMaskLayerDTOMono(content);
            } else if (InteractionTypeEnums.drag == apiZzSubjectContentVO.getInteraction()) {
                //拖拽
                return getContentDragDTOMono(content);
            } else if (InteractionTypeEnums.dub == apiZzSubjectContentVO.getInteraction()
            ) {
                // 配音
                return getContentInteractionDubDTOMono(content);
            } else if (InteractionTypeEnums.word_spelling == apiZzSubjectContentVO.getInteraction()) {
                // 单词拼写
                return getContentInteractionWordSpellingDTOMono(content);
            } else if (InteractionTypeEnums.single_choice == apiZzSubjectContentVO.getInteraction()) {
                // 选择
                return getContentInteractionSingleChoiceDTOMono(content, zzSubjectContent, apiZzSubjectContentVO.getTemplate());
            } else if (InteractionTypeEnums.classification == apiZzSubjectContentVO.getInteraction()) {
                // 分类
                return getContentInteractionClassificationDTOMono(content, apiZzSubjectContentVO.getTemplate());
            }
        }
        return null;
    }

    /**
     * 配音
     *
     * @param content
     * @return
     */
    private ContentInteractionDubDTO getContentInteractionDubDTOMono(String content) {
        JSONObject contentJson = JSON.parseObject(content);
        int wordSpelling = MapUtils.getInteger(contentJson, "wordSpelling", 1);
        if (1 == wordSpelling) {
            contentJson.remove("wordsList");
            ContentInteractionDubDTO contentInteractionDubDTO = contentJson.toJavaObject(ContentInteractionDubDTO.class);
            return getContentInteractionDubDTOWord(contentInteractionDubDTO);
        } else {
            contentJson.remove("wordsList");
            ContentInteractionDubDTO contentInteractionDubDTO = contentJson.toJavaObject(ContentInteractionDubDTO.class);
            return getContentInteractionDubDTOSentences(contentInteractionDubDTO);

        }

    }
    /**
     * 句子
     *
     * @param contentInteractionDubDTO
     * @return
     */
    @NotNull
    private ContentInteractionDubDTO getContentInteractionDubDTOSentences(ContentInteractionDubDTO
                                                                                  contentInteractionDubDTO) {
        Assert.isTrue(CollectionUtils.isNotEmpty(contentInteractionDubDTO.getSentences()), "题目配置单词有误");
        List<Long> fileIdList = Lists.newArrayList(
                contentInteractionDubDTO.getAudioFileId(),
                contentInteractionDubDTO.getImageFileId(),
                contentInteractionDubDTO.getSentencesAudioId(),
                contentInteractionDubDTO.getSentencesImageId()
        );
        // 设置主音频和图片 URL
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        contentInteractionDubDTO.setAudioFileURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getAudioFileId()));
        contentInteractionDubDTO.setImageFileURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getImageFileId()));
        contentInteractionDubDTO.setSentencesAudioURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getSentencesAudioId()));
        contentInteractionDubDTO.setSentencesImageURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getSentencesImageId()));
        return contentInteractionDubDTO;
    }
    /**
     * 配音单词
     *
     * @param contentInteractionDubDTO
     * @return
     */
    @NotNull
    private ContentInteractionDubDTO getContentInteractionDubDTOWord(ContentInteractionDubDTO contentInteractionDubDTO) {
        Assert.isTrue(CollectionUtils.isNotEmpty(contentInteractionDubDTO.getWordsId()), "题目未配置对应单词");
        List<ZzThesaurusWords> zzThesaurusWordsList = zzThesaurusWordsService.getOnLineByIds(contentInteractionDubDTO.getWordsId());
        Assert.isTrue(CollectionUtils.isNotEmpty(zzThesaurusWordsList), "题目配置单词有误");
        Collections.shuffle(zzThesaurusWordsList);
        contentInteractionDubDTO.setWordsId(Lists.newArrayList());
        contentInteractionDubDTO.setWordsList(Lists.newArrayList());
        for (ZzThesaurusWords zzThesaurusWords : zzThesaurusWordsList) {
            WordItemDTO wordItemDTO = new WordItemDTO();
            wordItemDTO.setWord(zzThesaurusWords.getWord());
            wordItemDTO.setId(zzThesaurusWords.getId());
            wordItemDTO.setWordItemAttrDTOList(Lists.newArrayList());
            contentInteractionDubDTO.getWordsList().add(wordItemDTO);
            contentInteractionDubDTO.getWordsId().add(wordItemDTO.getId());
        }
        List<ZzThesaurusAttr> allAttr = zzThesaurusAttrService.getByWordIdAndAttrOne(contentInteractionDubDTO.getWordsId(), Lists.newArrayList(WordsAttrEnum.audio.getCode()));
        Assert.isTrue(CollectionUtils.isNotEmpty(allAttr), "找不到该题目中单词对应相关音频信息");

        List<ZzThesaurusAttr> imageAttr = zzThesaurusAttrService.getByWordIdAndAttrOne(contentInteractionDubDTO.getWordsId(), IZzThesaurusAttrService.imageAttrCodeList);
        Assert.isTrue(CollectionUtils.isNotEmpty(allAttr), "找不到该题目中单词对应相关图片信息");


        // 构建 wordId -> Attr 映射
        Map<Long, ZzThesaurusAttr> attrMap = allAttr.stream().collect(Collectors.toMap(ZzThesaurusAttr::getWordId, Function.identity()));
        List<Long> fileIdList = Stream.of(Optional.ofNullable(contentInteractionDubDTO.getImageFileId()).stream(),
                Optional.ofNullable(contentInteractionDubDTO.getAudioFileId()).stream(), allAttr.stream().map(ZzThesaurusAttr::getAttrValue).map(s -> {
                            try {
                                return Optional.of(Long.parseLong(s));
                            } catch (NumberFormatException e) {
                                // 处理解析错误，比如忽略该值或记录日志
                                return Optional.<Long>empty();
                            }
                        }
                ).filter(Optional::isPresent).map(Optional::get)).flatMap(s -> s).filter(Objects::nonNull).collect(Collectors.toList());

        for (ZzThesaurusAttr zzThesaurusAttr : imageAttr) {
            if (NumberUtils.isCreatable(zzThesaurusAttr.getAttrValue())) {
                fileIdList.add(Long.valueOf(zzThesaurusAttr.getAttrValue()));
            }
        }
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        for (ZzThesaurusAttr zzThesaurusAttr : imageAttr) {
            if (NumberUtils.isCreatable(zzThesaurusAttr.getAttrValue()) && fileMap.containsKey(Long.valueOf(zzThesaurusAttr.getAttrValue()))) {
                contentInteractionDubDTO.setSentencesImageURL(getUrlFromMap(fileMap, Long.valueOf(zzThesaurusAttr.getAttrValue())));
            }
        }


        // 设置主音频和图片 URL
        contentInteractionDubDTO.setAudioFileURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getAudioFileId()));
        contentInteractionDubDTO.setImageFileURL(getUrlFromMap(fileMap, contentInteractionDubDTO.getImageFileId()));
        // 设置每个单词对应的图片
        for (WordItemDTO word : contentInteractionDubDTO.getWordsList()) {
            ZzThesaurusAttr attr = attrMap.get(word.getId());
            if (attr != null && attr.getAttrValue() != null) {
                String attrCode = attr.getAttrCode();
                if (attrCode.endsWith(WordsAttrEnum.image.getCode())) {
                    attrCode = attrCode.split("\\_")[1];
                }
                ZzUploadFileVO zzUploadFileVO = fileMap.get(Long.valueOf(attr.getAttrValue()));
                WordItemAttrDTO wordItemAttrDTO = new WordItemAttrDTO();
                wordItemAttrDTO.setBusinessType(attrCode);
                wordItemAttrDTO.setZzUploadFileVO(zzUploadFileVO);
                word.getWordItemAttrDTOList().add(wordItemAttrDTO);
            }
        }
        return contentInteractionDubDTO;
    }


    /**
     * 单词拼写
     *
     * @param content
     * @return
     */
    private ContentInteractionDubDTO getContentInteractionWordSpellingDTOMono(String content) {

        JSONObject contentJson = JSON.parseObject(content);
        int wordSpelling = MapUtils.getInteger(contentJson, "wordSpelling", 1);
        if (1 == wordSpelling) {
            contentJson.remove("wordsList");
            ContentInteractionDubDTO contentInteractionDubDTO = contentJson.toJavaObject(ContentInteractionDubDTO.class);
            return getContentInteractionDubDTOWord(contentInteractionDubDTO);
        } else {
            contentJson.remove("wordsList");
            ContentInteractionDubDTO contentInteractionDubDTO = contentJson.toJavaObject(ContentInteractionDubDTO.class);
            return getContentInteractionDubDTOSentences(contentInteractionDubDTO);

        }
    }
    /**
     * 拖拽
     *
     * @param content
     * @return
     */
    private ContentDragContentDTO getContentDragDTOMono(String content) {
        ContentDragContentDTO contentDragDTO = JSON.parseObject(content, ContentDragContentDTO.class);
        //处理图片
        List<Long> fileIdList = Stream.of(contentDragDTO.getImageFileId(), contentDragDTO.getAudioFileId()).filter(Objects::nonNull).collect(Collectors.toList());
        fileIdList.addAll(contentDragDTO.getDragFileIdList());
        fileIdList = fileIdList.stream().filter(Objects::nonNull).toList();
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        contentDragDTO.setImageFileURL(getUrlFromMap(fileMap, contentDragDTO.getImageFileId()));
        contentDragDTO.setAudioFileURL(getUrlFromMap(fileMap, contentDragDTO.getAudioFileId()));
        List<String> imgMainUrlList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(contentDragDTO.getDragFileIdList())) {
            for (Long id : contentDragDTO.getDragFileIdList()) {
                imgMainUrlList.add(getUrlFromMap(fileMap, id));
            }
            contentDragDTO.setMainImageList(imgMainUrlList.stream().filter(Objects::nonNull).collect(Collectors.toList()));
        }
        return contentDragDTO;
    }

    /**
     * 蒙层
     *
     * @param content
     * @return
     */
    private ContentInteractionMaskLayerDTO getContentInteractionMaskLayerDTOMono(String content) {
        ContentInteractionMaskLayerDTO contentInteractionMaskLayerDTO = JSON.parseObject(content, ContentInteractionMaskLayerDTO.class);
        // 定义跳过 key 列表
        List<String> skipKeys = Arrays.asList("mask_layer_top", "mask_layer_bottom", "show_model");
        Map<String, String> maskLayer = Optional.ofNullable(contentInteractionMaskLayerDTO.getMaskLayer()).orElse(Collections.emptyMap());
        // 收集所有需要加载文件的 fileId
        List<Long> fileIdList = maskLayer.entrySet().stream().filter(e -> !skipKeys.contains(e.getKey())).map(Map.Entry::getValue).map(val -> {
            try {
                return Long.valueOf(val);
            } catch (NumberFormatException ex) {
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
        Optional.ofNullable(contentInteractionMaskLayerDTO.getImageFileId()).ifPresent(fileIdList::add);
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        List<String> keys = Lists.newArrayList();
        keys.addAll(maskLayer.keySet());
        for (String key : keys) {
            String value = maskLayer.get(key);
            if (!skipKeys.contains(key)) {
                Long fileId = Long.valueOf(value);
                if (fileMap.containsKey(fileId)) {
                    maskLayer.put(key + "_url", getUrlFromMap(fileMap, fileId));
                }
            }
        }
        contentInteractionMaskLayerDTO.setMaskLayer(maskLayer);
        contentInteractionMaskLayerDTO.setImageFileURL(getUrlFromMap(fileMap, contentInteractionMaskLayerDTO.getImageFileId()));
        contentInteractionMaskLayerDTO.setImageFileId(contentInteractionMaskLayerDTO.getImageFileId());
        return contentInteractionMaskLayerDTO;
    }

    /**
     * 构建填空题
     *
     * @param content
     * @return
     */
    private ContentInteractionToFillInTheBlanksDTO getContentInteractionToFillInTheBlanksDTOMono(String content) {
        //填空 解析交互题型 DTO
        ContentInteractionToFillInTheBlanksDTO contentDTO = JSON.parseObject(content, ContentInteractionToFillInTheBlanksDTO.class);
        if (contentDTO.getWordSpelling() == null) {
            contentDTO.setWordSpelling(1);
        }
        Assert.isTrue(CollectionUtils.isNotEmpty(contentDTO.getWordsId()), "题目未配置对应单词");
        List<ZzThesaurusWords> zzThesaurusWordsList = zzThesaurusWordsService.getOnLineByIds(contentDTO.getWordsId());
        Assert.isTrue(CollectionUtils.isNotEmpty(zzThesaurusWordsList), "题目配置单词有误");
        ZzThesaurusWords rightZzThesaurusWords = zzThesaurusWordsService.getById(contentDTO.getRightWordId());
        // 异步获取单词列表
        Collections.shuffle(zzThesaurusWordsList);
        contentDTO.setWordsList(Lists.newArrayList());
        contentDTO.setWordsId(Lists.newArrayList());
        for (ZzThesaurusWords zzThesaurusWords : zzThesaurusWordsList) {
            contentDTO.getWordsList().add(zzThesaurusWords.getWord());
            contentDTO.getWordsId().add(zzThesaurusWords.getId());
        }
        contentDTO.setRightWord(rightZzThesaurusWords.getWord());
        List<Long> fileIdList = Stream.of(contentDTO.getImageFileId(), contentDTO.getAudioFileId()).filter(Objects::nonNull).collect(Collectors.toList());
        // 加载文件映射
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        // 设置音频 URL
        contentDTO.setAudioFileURL(getUrlFromMap(fileMap, contentDTO.getAudioFileId()));
        // 设置图片 URL
        contentDTO.setImageFileURL(getUrlFromMap(fileMap, contentDTO.getImageFileId()));
        return contentDTO;
    }

    /**
     * 构建联线题
     *
     * @param content
     * @param interactionTemplateEnums
     * @return
     */
    private ContentInteractionLineDTO getContentInteractionLineDTOMono(String content, InteractionTemplateEnums interactionTemplateEnums) {
        // 原始内容映射为 DTO
        JSONObject contetnJSON = JSON.parseObject(content);
        contetnJSON.remove("wordsList");
        // 原始内容映射为 DTO
        ContentInteractionLineDTO interactionLineDTO = contetnJSON.toJavaObject(ContentInteractionLineDTO.class);
        if (InteractionTemplateEnums.line_custom == interactionTemplateEnums) {
            //特殊处理
            List<ZzUploadFileVO> firstMainImageFileUploadFileVO = zzUploadFileManager.getByIdList(interactionLineDTO.getFirstMainImageFileIdList());
            List<ZzUploadFileVO> secondMainImageFileUploadFileVO = zzUploadFileManager.getByIdList(interactionLineDTO.getSecondMainImageFileIdList());
            interactionLineDTO.setFirstMainImageFileUploadFileVO(firstMainImageFileUploadFileVO);
            interactionLineDTO.setSecondMainImageFileUploadFileVO(secondMainImageFileUploadFileVO);
            List<Long> fileIdList = Lists.newArrayList(interactionLineDTO.getImageFileId(), interactionLineDTO.getAudioFileId()).stream().filter(Objects::nonNull).collect(Collectors.toList());
            Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
            // 设置主音频和图片 URL
            interactionLineDTO.setAudioFileURL(getUrlFromMap(fileMap, interactionLineDTO.getAudioFileId()));
            interactionLineDTO.setImageFileURL(getUrlFromMap(fileMap, interactionLineDTO.getImageFileId()));
            return interactionLineDTO;
        }
        Assert.isTrue(CollectionUtils.isNotEmpty(interactionLineDTO.getWordsId()), "题目未配置对应单词");
        List<ZzThesaurusWords> zzThesaurusWordsList = zzThesaurusWordsService.getOnLineByIds(interactionLineDTO.getWordsId());
        Assert.isTrue(CollectionUtils.isNotEmpty(zzThesaurusWordsList), "题目配置单词有误");
        Collections.shuffle(zzThesaurusWordsList);
        interactionLineDTO.setWordsId(Lists.newArrayList());
        interactionLineDTO.setWordsList(Lists.newArrayList());
        for (ZzThesaurusWords zzThesaurusWords : zzThesaurusWordsList) {
            WordItemDTO wordItemDTO = new WordItemDTO();
            wordItemDTO.setWord(zzThesaurusWords.getWord());
            wordItemDTO.setId(zzThesaurusWords.getId());
            wordItemDTO.setWordItemAttrDTOList(Lists.newArrayList());
            interactionLineDTO.getWordsList().add(wordItemDTO);
            interactionLineDTO.getWordsId().add(wordItemDTO.getId());
        }
        List<String> attrCodeList = Lists.newArrayList();
        if (interactionTemplateEnums == InteractionTemplateEnums.word_to_image
                || interactionTemplateEnums == InteractionTemplateEnums.image_to_audio) {
            attrCodeList.addAll(IZzThesaurusAttrService.imageAttrCodeList);
        } else if (interactionTemplateEnums == InteractionTemplateEnums.word_to_audio) {
            attrCodeList.add(WordsAttrEnum.audio.getCode());
        }

        List<ZzThesaurusAttr> allAttr = zzThesaurusAttrService.getByWordIdAndAttrOne(interactionLineDTO.getWordsId(), attrCodeList);
        Assert.isTrue(CollectionUtils.isNotEmpty(allAttr), "找不到该题目中单词对应相关配置信息");
        if (interactionTemplateEnums == InteractionTemplateEnums.image_to_audio) {
            // 加载单词属性(音频)
            List<ZzThesaurusAttr> attrAudioFlux = zzThesaurusAttrService.getByWordIdAndAttrOne(interactionLineDTO.getWordsId(), Lists.newArrayList(WordsAttrEnum.audio.getCode()));
            Assert.isTrue(CollectionUtils.isNotEmpty(attrAudioFlux), "找不到该题目中单词对应相关音频信息");
            Set<Long> imageWordIds = allAttr.stream().map(ZzThesaurusAttr::getWordId).collect(Collectors.toSet());
            Set<Long> audioWordIds = attrAudioFlux.stream().map(ZzThesaurusAttr::getWordId).collect(Collectors.toSet());
            imageWordIds.retainAll(audioWordIds);
            allAttr.addAll(attrAudioFlux);
            allAttr = allAttr.stream().filter(attr -> imageWordIds.contains(attr.getWordId())).collect(Collectors.toList());
        }
        List<Long> fileIdList = Stream.of(Optional.ofNullable(interactionLineDTO.getImageFileId()).stream(), Optional.ofNullable(interactionLineDTO.getAudioFileId()).stream(), allAttr.stream().map(ZzThesaurusAttr::getAttrValue).map(s -> {
            try {
                return Optional.of(Long.parseLong(s));
            } catch (NumberFormatException e) {
                // 处理解析错误，比如忽略该值或记录日志
                return Optional.<Long>empty();
            }
        }).filter(Optional::isPresent).map(Optional::get)).flatMap(s -> s).filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        // 设置主音频和图片 URL
        interactionLineDTO.setAudioFileURL(getUrlFromMap(fileMap, interactionLineDTO.getAudioFileId()));
        interactionLineDTO.setImageFileURL(getUrlFromMap(fileMap, interactionLineDTO.getImageFileId()));
        // 设置每个单词对应的图片
        for (WordItemDTO word : interactionLineDTO.getWordsList()) {
            List<WordItemAttrDTO> wordItemAttrDTOList = Lists.newArrayList();
            for (Iterator<ZzThesaurusAttr> iterator = allAttr.iterator(); iterator.hasNext(); ) {
                ZzThesaurusAttr zzThesaurusAttr = iterator.next();
                if (zzThesaurusAttr.getWordId().equals(word.getId())) {
                    WordItemAttrDTO wordItemAttrDTO = new WordItemAttrDTO();
                    String attrCode = zzThesaurusAttr.getAttrCode();
                    if (attrCode.endsWith(WordsAttrEnum.image.getCode())) {
                        attrCode = attrCode.split("\\_")[1];
                    }
                    wordItemAttrDTO.setBusinessType(attrCode);
                    wordItemAttrDTO.setZzUploadFileVO(fileMap.get(Long.valueOf(zzThesaurusAttr.getAttrValue())));
                    wordItemAttrDTOList.add(wordItemAttrDTO);
                }
            }
            word.setWordItemAttrDTOList(wordItemAttrDTOList);
        }
        return interactionLineDTO;
    }


    /**
     * 选择
     *
     * @param content
     * @param interactionTemplateEnums
     * @return
     */
    private ContentInteractionSingleChoiceDTO getContentInteractionSingleChoiceDTOMono(String content, ZzSubjectContent zzSubjectContent, InteractionTemplateEnums interactionTemplateEnums) {
        JSONObject contentJSON = JSON.parseObject(content);
        contentJSON.remove("wordsList");
        ContentInteractionSingleChoiceDTO contentInteractionSingleChoiceDTO = contentJSON.toJavaObject(ContentInteractionSingleChoiceDTO.class);

        Assert.isTrue(CollectionUtils.isNotEmpty(contentInteractionSingleChoiceDTO.getWordsId()), "题目未配置对应单词");
        contentInteractionSingleChoiceDTO.setWordsList(Lists.newArrayList());
        Long rightWordId = contentInteractionSingleChoiceDTO.getWordsId().get(0);
        contentInteractionSingleChoiceDTO.setRightWordId(rightWordId);
        List<String> attrCodeList = Lists.newArrayList();
        if (interactionTemplateEnums == InteractionTemplateEnums.image_select_word || interactionTemplateEnums == InteractionTemplateEnums.word_select_image || interactionTemplateEnums == InteractionTemplateEnums.audio_select_image || interactionTemplateEnums == InteractionTemplateEnums.image_select_audio) {
            //看图选择#看词选图
            attrCodeList.addAll(IZzThesaurusAttrService.imageAttrCodeList);
        } else if (interactionTemplateEnums == InteractionTemplateEnums.audio_select_word) {
            // 听音选词
            attrCodeList.add(WordsAttrEnum.audio.getCode());
        }
        List<Long> filterWordIdList = Lists.newArrayList();
        //#找对应绘本
        ZzPictureNode zzPictureNode = this.zzPictureNodeService.getById(zzSubjectContent.getNodeId());
        if (null != zzPictureNode) {
            if (null != zzPictureNode && null != zzPictureNode.getNodeType()) {
                //课件
                if (1 == zzPictureNode.getNodeType()) {
                    ZzPictureBook zzPictureBook = this.zzPictureBookService.getById(zzPictureNode.getPictureBookId());
                    if (null != zzPictureBook) {
                        List<String> words = JSON.parseArray(zzPictureBook.getWords(), String.class);
                        List<ZzThesaurusWords> zzThesaurusWords = this.zzThesaurusWordsService.list(Wrappers.lambdaQuery(ZzThesaurusWords.class).in(ZzThesaurusWords::getWord, words)
                                );
                        filterWordIdList.addAll(zzThesaurusWords.stream().map(ZzThesaurusWords::getId).collect(Collectors.toList()));
                    }
                } else if (2 == zzPictureNode.getNodeType()) {
                    //作业
                    ZzPictureNode dayZzPictureNode = zzPictureNodeService.getById(zzPictureNode.getpNodeId());
                    ZzPictureBook zzPictureBook = this.zzPictureBookService.getById(zzPictureNode.getPictureBookId());
                    if (null != zzPictureBook) {
                        List<String> words = JSON.parseArray(zzPictureBook.getWords(), String.class);
                        List<ZzThesaurusWords> zzThesaurusWords = this.zzThesaurusWordsService
                                .list(Wrappers.lambdaQuery(ZzThesaurusWords.class).in(ZzThesaurusWords::getWord, words)
                                );
                        filterWordIdList.addAll(zzThesaurusWords.stream().map(ZzThesaurusWords::getId).collect(Collectors.toList()));
                    }
                }
            }
        }
        filterWordIdList.add(rightWordId);
        Collections.shuffle(filterWordIdList);
        // 获取打乱后的 wordId 列表
        List<ZzThesaurusWords> zzThesaurusWordsList = zzThesaurusWordsService.getOnLineByIds(filterWordIdList);
        Assert.isTrue(CollectionUtils.isNotEmpty(zzThesaurusWordsList), "题目配置单词有误");
        for (ZzThesaurusWords zzThesaurusWords : zzThesaurusWordsList) {
            WordItemDTO wordItemDTO = new WordItemDTO();
            wordItemDTO.setWord(zzThesaurusWords.getWord());
            wordItemDTO.setId(zzThesaurusWords.getId());
            wordItemDTO.setWordItemAttrDTOList(Lists.newArrayList());
            contentInteractionSingleChoiceDTO.getWordsList().add(wordItemDTO);
            contentInteractionSingleChoiceDTO.getWordsId().add(wordItemDTO.getId());
            rightWordId = zzThesaurusWords.getId();
        }
        List<ZzThesaurusAttr> allAttr = zzThesaurusAttrService.getByWordIdAndAttrOne(filterWordIdList, attrCodeList);
        Assert.isTrue(CollectionUtils.isNotEmpty(allAttr), "找不到该题目中单词对应相关图片信息");
        if (interactionTemplateEnums == InteractionTemplateEnums.image_to_audio || interactionTemplateEnums == InteractionTemplateEnums.audio_select_image || interactionTemplateEnums == InteractionTemplateEnums.image_select_audio) {
            // 加载单词属性(音频)
            List<ZzThesaurusAttr> attrAudioFlux = zzThesaurusAttrService.getByWordIdAndAttrOne(contentInteractionSingleChoiceDTO.getWordsId(), Lists.newArrayList(WordsAttrEnum.audio.getCode()));
            Assert.isTrue(CollectionUtils.isNotEmpty(attrAudioFlux), "找不到该题目中单词对应相关图片信息");
            Set<Long> imageWordIds = allAttr.stream().map(ZzThesaurusAttr::getWordId).collect(Collectors.toSet());
            Set<Long> audioWordIds = attrAudioFlux.stream().map(ZzThesaurusAttr::getWordId).collect(Collectors.toSet());
            imageWordIds.retainAll(audioWordIds);
            allAttr.addAll(attrAudioFlux);
            allAttr = allAttr.stream().filter(attr -> imageWordIds.contains(attr.getWordId())).collect(Collectors.toList());
        }
        List<Long> fileIdList = Stream.of(Optional.ofNullable(contentInteractionSingleChoiceDTO.getImageFileId()).stream(), Optional.ofNullable(contentInteractionSingleChoiceDTO.getAudioFileId()).stream(), allAttr.stream().map(ZzThesaurusAttr::getAttrValue).map(s -> {
            try {
                return Optional.of(Long.parseLong(s));
            } catch (NumberFormatException e) {
                // 处理解析错误，比如忽略该值或记录日志
                return Optional.<Long>empty();
            }
        }).filter(Optional::isPresent).map(Optional::get)).flatMap(s -> s).filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);
        // 设置主音频和图片 URL
        contentInteractionSingleChoiceDTO.setAudioFileURL(getUrlFromMap(fileMap, contentInteractionSingleChoiceDTO.getAudioFileId()));
        contentInteractionSingleChoiceDTO.setImageFileURL(getUrlFromMap(fileMap, contentInteractionSingleChoiceDTO.getImageFileId()));
        List<Long> allWordIds = allAttr.stream().map(ZzThesaurusAttr::getWordId).collect(Collectors.toList());
        Assert.isTrue(allWordIds.contains(rightWordId), "请检查题目配置");
        for (Iterator<WordItemDTO> wordItemDTOIterator = contentInteractionSingleChoiceDTO.getWordsList().iterator(); wordItemDTOIterator.hasNext(); ) {
            WordItemDTO word = wordItemDTOIterator.next();
            if (!allWordIds.contains(word.getId())) {
                wordItemDTOIterator.remove();
                continue;
            }
            List<WordItemAttrDTO> wordItemAttrDTOList = Lists.newArrayList();
            for (Iterator<ZzThesaurusAttr> iterator = allAttr.iterator(); iterator.hasNext(); ) {
                ZzThesaurusAttr zzThesaurusAttr = iterator.next();
                if (zzThesaurusAttr.getWordId().equals(word.getId())) {
                    WordItemAttrDTO wordItemAttrDTO = new WordItemAttrDTO();
                    String attrCode = zzThesaurusAttr.getAttrCode();
                    if (attrCode.endsWith(WordsAttrEnum.image.getCode())) {
                        attrCode = attrCode.split("\\_")[1];
                    }
                    wordItemAttrDTO.setBusinessType(attrCode);
                    wordItemAttrDTO.setZzUploadFileVO(fileMap.get(Long.valueOf(zzThesaurusAttr.getAttrValue())));
                    wordItemAttrDTOList.add(wordItemAttrDTO);
                }
            }
            word.setWordItemAttrDTOList(wordItemAttrDTOList);
        }
        return contentInteractionSingleChoiceDTO;
    }


    /**
     * 分类
     *
     * @param content
     * @param interactionTemplateEnums
     * @return
     */
    private ContentInteractionClassificationDTO getContentInteractionClassificationDTOMono(String content, InteractionTemplateEnums interactionTemplateEnums) {
        JSONObject contetnJSON = JSON.parseObject(content);
        contetnJSON.remove("wordsList");
        ContentInteractionClassificationDTO contentInteractionClassificationDTO = contetnJSON.toJavaObject(ContentInteractionClassificationDTO.class);

        Assert.isTrue(CollectionUtils.isNotEmpty(contentInteractionClassificationDTO.getWordsId()), "题目未配置对应单词");
        // 获取打乱后的 wordId 列表
        List<ZzThesaurusWords> zzThesaurusWordsList = zzThesaurusWordsService.getOnLineByIds(contentInteractionClassificationDTO.getWordsId());
        Assert.isTrue(CollectionUtils.isNotEmpty(zzThesaurusWordsList), "题目配置单词有误");
        Collections.shuffle(zzThesaurusWordsList);
        contentInteractionClassificationDTO.setWordsId(Lists.newArrayList());
        contentInteractionClassificationDTO.setWordsList(Lists.newArrayList());
        for (ZzThesaurusWords zzThesaurusWords : zzThesaurusWordsList) {
            WordItemDTO wordItemDTO = new WordItemDTO();
            wordItemDTO.setWord(zzThesaurusWords.getWord());
            wordItemDTO.setId(zzThesaurusWords.getId());
            wordItemDTO.setWordItemAttrDTOList(Lists.newArrayList());
            contentInteractionClassificationDTO.getWordsList().add(wordItemDTO);
            contentInteractionClassificationDTO.getWordsId().add(wordItemDTO.getId());
        }

        List<String> attrCodeList = Lists.newArrayList();

        attrCodeList.addAll(IZzThesaurusAttrService.imageAttrCodeList);
        List<ZzThesaurusAttr> allAttr = zzThesaurusAttrService.getByWordIdAndAttrOne(contentInteractionClassificationDTO.getWordsId(), attrCodeList);

        List<Long> fileIdList = Stream.of(Optional.ofNullable(contentInteractionClassificationDTO.getImageFileId()).stream(), Optional.ofNullable(contentInteractionClassificationDTO.getAudioFileId()).stream(), allAttr.stream().map(ZzThesaurusAttr::getAttrValue).map(s -> {
            try {
                return Optional.of(Long.parseLong(s));
            } catch (NumberFormatException e) {
                // 处理解析错误，比如忽略该值或记录日志
                return Optional.<Long>empty();
            }
        }).filter(Optional::isPresent).map(Optional::get)).flatMap(s -> s).filter(Objects::nonNull).collect(Collectors.toList());
        Map<Long, ZzUploadFileVO> fileMap = this.zzUploadFileManager.getMapByIdList(fileIdList);

        List<ZzThesaurusTagDTO> zzThesaurusTagList = Lists.newArrayList();

        List<ZzThesaurusWordsTagRelated> zzThesaurusWordsTagRelatedList = this.zzThesaurusWordsTagRelatedService.list(Wrappers.lambdaQuery(ZzThesaurusWordsTagRelated.class)
                .in(ZzThesaurusWordsTagRelated::getWordId, contentInteractionClassificationDTO.getWordsId())
                .apply("tag_id in(select id from zz_thesaurus_tag where deleted=0)"));
        if (CollectionUtils.isNotEmpty(zzThesaurusWordsTagRelatedList)) {
            ArrayListMultimap<Long, Long> arrayListMultimap = ArrayListMultimap.create();
            for (ZzThesaurusWordsTagRelated zzThesaurusWordsTagRelated : zzThesaurusWordsTagRelatedList) {
                arrayListMultimap.put(zzThesaurusWordsTagRelated.getWordId(), zzThesaurusWordsTagRelated.getTagId());
            }
            List<Long> tagIdList = zzThesaurusWordsTagRelatedList.stream().map(ZzThesaurusWordsTagRelated::getTagId).collect(Collectors.toList());
            List<ZzThesaurusTag> zzThesaurusTags = this.zzThesaurusTagService.list(Wrappers.lambdaQuery(ZzThesaurusTag.class)
                    .in(ZzThesaurusTag::getId, tagIdList));
            if (CollectionUtils.isNotEmpty(zzThesaurusTags)) {
                for (WordItemDTO word : contentInteractionClassificationDTO.getWordsList()) {
                    List<WordItemAttrDTO> wordItemAttrDTOList = Lists.newArrayList();
                    for (Iterator<ZzThesaurusAttr> iterator = allAttr.iterator(); iterator.hasNext(); ) {
                        ZzThesaurusAttr zzThesaurusAttr = iterator.next();
                        if (zzThesaurusAttr.getWordId().equals(word.getId())) {
                            WordItemAttrDTO wordItemAttrDTO = new WordItemAttrDTO();
                            String attrCode = zzThesaurusAttr.getAttrCode();
                            if (attrCode.endsWith(WordsAttrEnum.image.getCode())) {
                                attrCode = attrCode.split("\\_")[1];
                            }
                            wordItemAttrDTO.setBusinessType(attrCode);
                            wordItemAttrDTO.setZzUploadFileVO(fileMap.get(Long.valueOf(zzThesaurusAttr.getAttrValue())));
                            wordItemAttrDTOList.add(wordItemAttrDTO);
                        }
                    }
                    word.setWordItemAttrDTOList(wordItemAttrDTOList);
                }
                for (ZzThesaurusTag thesaurusTag : zzThesaurusTags) {
                    ZzThesaurusTagDTO zzThesaurusTagDTO = new ZzThesaurusTagDTO();
                    zzThesaurusTagDTO.setTagName(thesaurusTag.getTagName());
                    zzThesaurusTagDTO.setId(thesaurusTag.getId());
                    zzThesaurusTagList.add(zzThesaurusTagDTO);
                }
                //设置单词对应的标签
                for (WordItemDTO wordItemDTO : contentInteractionClassificationDTO.getWordsList()) {
                    List<Long> tagId = arrayListMultimap.get(wordItemDTO.getId());
                    Collections.shuffle(tagId);
                    wordItemDTO.setId(tagId.get(0));
                }


            }
        }
        contentInteractionClassificationDTO.setZzThesaurusTagList(zzThesaurusTagList);
        return contentInteractionClassificationDTO;
    }

    /**
     * 设置url
     *
     * @param map
     * @param id
     * @return
     */
    private String getUrlFromMap(Map<Long, ZzUploadFileVO> map, Long id) {
        return (id != null && map.containsKey(id)) ? map.get(id).getUrl() : null;
    }
}